package com.lingtu.searchtest04.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.lingtu.searchtest04.cofig.GulimallElasticSearchConfig;
import com.lingtu.searchtest04.entity.SearchPoint;
import com.lingtu.searchtest04.euam.SearchPointEnum;
import com.lingtu.searchtest04.service.SearchService;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.DistanceUnit;
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.GeoDistanceQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class SearchServiceImpl implements SearchService {

    @Autowired
    private RestHighLevelClient client;

    @Override
    public List<SearchPoint> searchPointByName(String name) throws IOException {
        String key = "name";
        return searchByNameTypeId(key,name,null);
    }

    @Override
    public List<SearchPoint> searchPointByLanLon(SearchPoint point) throws IOException {
        String text= JSONObject.toJSONString(point);

        List<SearchPoint> searchPointList = searchPointByID(text);
        String Location = searchPointList.get(0).getLocation();
        String[] re = Location.split(",");//用split()函数直接分割
        Double lat = Double.parseDouble(re[0]);
        Double lon = Double.parseDouble(re[1]);
        //拼接条件
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//        QueryBuilder isdeleteBuilder = QueryBuilders.termQuery("isdelete", false);
        // 以某点为中心，搜索指定范围
        GeoDistanceQueryBuilder distanceQueryBuilder = new GeoDistanceQueryBuilder("location");
        distanceQueryBuilder.point(lat,lon);
        //查询单位：km
        distanceQueryBuilder.distance("5", DistanceUnit.KILOMETERS);
        boolQueryBuilder.filter(distanceQueryBuilder);

        String key = "location";
        return searchByNameTypeId(key,null,boolQueryBuilder);
    }

    @Override
    public List<SearchPoint> searchPointByID(String id) throws IOException {
        String key = "id";
        return searchByNameTypeId(key,id,null);
    }

    @Override
    public List<SearchPoint> searchPointByType(String type) throws IOException {
        String key = "type";
        return searchByNameTypeId(key,type,null);
    }

    List<SearchPoint> searchByNameTypeId(String key,String value,BoolQueryBuilder boolQueryBuilder) throws IOException {
        //1.创建检索条件
        SearchRequest searchRequest = new SearchRequest();
        //1.1指定索引
        searchRequest.indices();
        //1.2指定dsl,检索条件。 封装条件
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //1.3构建检索条件
        // 将json数据解析成JSONObject对象，以key-value形式存在
        String str = null;
        if (value != null){
            JSONObject jsonObject = JSONObject.parseObject(value);
            str = jsonObject.getString(key);
        }
        // 获取对应的数据【返回值为String类型】 参数为对应key名称
        System.out.println(str);

        if(key == "id"){
            sourceBuilder.query(QueryBuilders.termQuery(key, str));//条件添加进去
        }else if (key == "location"){
            sourceBuilder.query(boolQueryBuilder).size(10000);
        }else {
            sourceBuilder.query(QueryBuilders.matchQuery(key,str)).size(10000);//条件添加进去
        }
        System.out.println("检索条件：" + sourceBuilder.toString());//条件打印
        //1.4封装条件
        searchRequest.source(sourceBuilder);
        //2.执行检索
        SearchResponse searchResponse = client.search(searchRequest,GulimallElasticSearchConfig.COMMON_OPTIONS);
        //3.分析结果
        //System.out.println(searchResponse.toString());//条件执行完的查询结果？
        //3.1获取结果
        SearchHits hits = searchResponse.getHits();
        SearchHit[] searchHits = hits.getHits();
        List<SearchPoint> searchPointList = new ArrayList<>();
        for (SearchHit hit : searchHits) {
//            hit.getIndex();hit.getId();hit.getType();//方式一获取结果
            String string = hit.getSourceAsString();
            SearchPoint searchPoint = new SearchPoint();
            searchPoint = JSONObject.parseObject(string,SearchPoint.class);
            searchPointList.add(searchPoint);
        }
        System.out.println("结果的长度：" + searchPointList.size());
        return searchPointList;
    }

}
